package com.self.ry.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 移位操作类
 * Created by my on 2018/10/25.
 */
public final class ShiftUtil {


    /**
     * 返回指定位的值
     * @param src int -- 元数据
     * @param position 字节中的位置
     * @return 返回值 0或1
     */
    public static int getValueByPosition(int src, int position){
        return (src >> position) & 1;
    }

    /**
     * 返回指定位的值
     * @param src byte -- 元数据
     * @param position 字节中的位置
     * @return 返回值 0或1
     */
    public static int getValueByPosition(byte src, int position){
        return (src >> position) & 1;
    }

    /**
     * 将HEX转成二进制字符串
     * @param hex
     * @param format
     * @return
     */
    public static String hex2BinaryStr(String hex, String format) {
        Integer value = Integer.valueOf(hex, 16);
        if (StringUtils.isBlank(format)) {
            int len = hex.length();
            len = (len & 1) == 0 ? len : len + 1;
            len >>= 1; // 除以2
            len <<= 3; // 乘以8
            format = "%" + len + "s";
        }

        String s = Integer.toBinaryString(value);
        s = String.format(format, s).replace(" ", "0");
        return s;
    }

    private static final String SPLIT_1 = "-";
    private static final String SPLIT_2 = ",";

    /**
     * 位置信息解析
     *
     * @param position 含有（- 或 ,）分隔符的位置信息
     * @param split    指定分隔符
     * @return
     */
    public static List<Integer> positionList(String position, String split) {
        if (StringUtils.isBlank(position)) return null;
        List<Integer> result = new ArrayList<>();

        List<String> list = new ArrayList<>();
        if (StringUtils.isNotBlank(split)) {
            list.addAll(Arrays.asList(position.split(split)));
        } else if (position.indexOf(SPLIT_1) > -1 && position.indexOf(SPLIT_2) > -1) {
            String[] strings = position.split(SPLIT_2);
            for (String str : strings) {
                if (str.indexOf(SPLIT_1) == -1) {
                    result.add(Integer.valueOf(str));
                    continue;
                }

                List<String> strings1 = Arrays.asList(str.split(SPLIT_1));
                int min = strings1.stream().mapToInt(Integer::valueOf).min().getAsInt();
                int max = strings1.stream().mapToInt(Integer::valueOf).max().getAsInt();
                for (int m = max; m >= min; m--) {
                    result.add(m);
                }
            }

            result = result.stream().sorted((a, b) -> a.compareTo(b)).collect(Collectors.toList());
        } else if (position.indexOf(SPLIT_1) > -1) {
            List<String> strings = Arrays.asList(position.split(SPLIT_1));
            int min = strings.stream().mapToInt(Integer::valueOf).min().getAsInt();
            int max = strings.stream().mapToInt(Integer::valueOf).max().getAsInt();
            for (int m = max; m >= min; m--) {
                result.add(m);
            }
        } else if (position.indexOf(SPLIT_2) > -1) {
            List<Integer> collect = Arrays.asList(position.split(SPLIT_2)).stream().map(Integer::valueOf).sorted((a, b) -> a.compareTo(b)).collect(Collectors.toList());
            result.addAll(collect);
        } else {
            result.add(Integer.valueOf(position));
        }

        return result;
    }

    /**
     * 判断一个正整数 n 是否为 2 的幂次方
     * @param n
     * @return
     */
    public static boolean isPower2Square(int n) {
        return (n & (n - 1)) == 0;
    }

    /**
     * 计算指定整数的二进制中1的个数
     * @param n
     * @return
     */
    public static int count1InNumber(int n) {
        int count = 0;
        while (n != 0) {
            count++;
            n = n & (n - 1);
        }

        return count;
    }

    /**
     * 将指定的整数n 转换为 m ，需要改变多少二进制位
     * @param n
     * @param m
     * @return
     */
    public static int changeNToM(int n, int m) {
        int t = n ^ m; // 异或
        return count1InNumber(t);
    }


    /**
     * 根据 输入的范围，返回集合
     * @param position bit位信息，如 15-13：表示bit15-bit13
     * @return 返回bit位的集合,默认是降序
     */
    public static List<Integer> positionList(String position) {
        return positionList(position, null);
    }

    public static void main(String[] args) {
        // 转成二进制字符串
        String format = "%" + 10 + "s";
        System.out.println(hex2BinaryStr("0A", null));

        // bit位集合
        List<Integer> poList = positionList("15-13");
        // 15 14 13
        poList.forEach(System.out::println);
    }
}
